package com.hzhc.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hzhc.entity.*;
import com.hzhc.enumBean.ResultUtilCodeEnum;
import com.hzhc.mapper.*;
import com.hzhc.service.SysUserSecurityService;
import com.hzhc.service.SysUserService;
import com.hzhc.utils.ResultUtil;
import com.hzhc.vo.SysUserVo;
import lombok.RequiredArgsConstructor;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;


/**
 * <p>
 * 系统用户 服务实现类
 * </p>
 *
 * @author duanhm
 * @since 2019-07-22
 */
@Service
@RequiredArgsConstructor
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    private final SysUserMapper userMapper;

    private final SysUserRoleMapper userRoleMapper;

    private final UserMemberMapper userMemberMapper;

    private final SysUserSecurityService securityService;

    private final SysOrganizationMapper sysOrganizationMapper;

    private final SysOrganizationRoleMapper sysOrganizationRoleMapper;

    /**
     * 用户登入
     */
    @Override
    public SysUserVo login(String username, String password) {
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        wrapper.eq("loginname", username).eq("password", password);
        SysUser suer = userMapper.selectOne(wrapper);
        if (suer != null && suer.getStatus()==1) {
            SysUserVo vo = new SysUserVo();
            vo.setId(suer.getId());
            vo.setRealname(suer.getRealname());
            vo.setLoginname(suer.getLoginname());
            vo.setUserMemberFlag(1);
            vo.setAvatarUrl(suer.getAvatarUrl());
            vo.setLastLoginTime(suer.getLastLoginTime());
            vo.setLoginTime(suer.getLoginTime());
            vo.setOrgId(suer.getOrgId());
            if(suer.getOrgId()!=null){
                SysOrganization sysOrganization = sysOrganizationMapper.selectById(suer.getOrgId());
                vo.setAccountPermission(sysOrganization.getAccountPermission());
            }
            return vo;
        }
        return null;
    }

    @Override
    public List<SysUserVo> findUserList(Page<SysUserVo> page, SysUserVo searchData) {
        IPage<SysUserVo> retusermap = userMapper.findAllUserPage(page, searchData);
        List<SysUserVo> list = retusermap.getRecords();
        return list;
    }

    @Override
    public ResultUtil<T> saveUser(SysUserVo user, String upfolder, String accessPath) {
        //java校验密码正则
        ResultUtil<T> rel = securityService.checkPasswordLevel(user.getRealPassword());
        if (rel.getCode()==400){
            return rel;
        }

        Boolean ret = false;
        SysUser nuser = new SysUser();
        user.setCreateTime(LocalDateTime.now());
        BeanUtils.copyProperties(user, nuser);
        ret = save(nuser);
        // 保存用户角色
        if (StrUtil.isNotBlank(user.getRoleId())) {
            List<String> split = StrUtil.split(user.getRoleId(), ",");
            for (String s:split) {
                if (StrUtil.isNotBlank(s)) {
                    SysUserRole userRole = new SysUserRole();
                    userRole.setRoleId(Long.parseLong(s));
                    userRole.setUserId(nuser.getId());
                    userRoleMapper.insert(userRole);
                }
            }
        }
        if(user.getFile()!=null) {
            saveFiles(nuser.getId(), user.getFile(), upfolder, accessPath);
        }
        return ret ? ResultUtil.ok() : ResultUtil.fail();
    }

    @Override
    public ResultUtil<T> updateDelete(String ids) {
        List<Long> adminIds = Arrays.asList(1L, 3L, 4L, 5L, 6L);
        String[] idss = ids.split(",");
        for (String s : idss) {
            if (StrUtil.isBlank(s)) {
                continue;
            }
            if (adminIds.contains(Long.parseLong(s.trim()))) {
                return ResultUtil.build(ResultUtilCodeEnum.NO_GLYZH);
            }
        }
        boolean b = baseMapper.update(null, new UpdateWrapper<SysUser>()
                .eq("status", 1)
                .in("id", idss)
                .set("status", 0)
        ) > 0;
        return b ? ResultUtil.ok() : ResultUtil.fail();
    }

    @Override
    public boolean checkUserByField(String field, SysUserVo data) {
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<SysUser>();
        queryWrapper.eq(field, data.getMobile());
        if (data.getId() != null) {
            queryWrapper.ne("id", data.getId());
        }
        List<SysUser> list = userMapper.selectList(queryWrapper);
        if (list.size() > 0) {
            return true;// 返回true 已经存在
        }
        return false;
    }

    @Override
    public ResultUtil<T> updateUser(SysUserVo data, String upfolder, String accessPath) {
        SysUser user = userMapper.selectById(data.getId());
        user.setGonghao(data.getGonghao());
        user.setLoginname(data.getLoginname());
        user.setOrgId(data.getOrgId());
        user.setSex(data.getSex());
        user.setMobile(data.getMobile());
        if (data.getStatus() == null) {
            user.setStatus(0);
        } else {
            user.setStatus(1);
        }
        user.setRealname(data.getRealname());
        int ret = userMapper.updateById(user);
        // 根据用户组织账号权限确定角色是否去除
        if (user.getOrgId()!=null) {
            SysOrganization sysOrganization = sysOrganizationMapper.selectById(user.getOrgId());
            if(sysOrganization!=null&&sysOrganization.getAccountPermission().equals(0)){
                List<Long> roleIds = new ArrayList<>();
                List<SysOrganizationRole> sysOrganizationRoles = sysOrganizationRoleMapper.selectList(Wrappers.<SysOrganizationRole>lambdaQuery()
                        .eq(SysOrganizationRole::getOrganizationId, user.getOrgId()));
                if(!sysOrganizationRoles.isEmpty()){
                    roleIds = sysOrganizationRoles.stream().map(SysOrganizationRole::getRoleId).distinct().collect(Collectors.toList());
                }
                //删除所有不是该组织的用户角色
                userRoleMapper.delete(Wrappers.<SysUserRole>lambdaQuery()
                        .notIn(!roleIds.isEmpty(),SysUserRole::getRoleId,roleIds)
                        .eq(SysUserRole::getUserId,user.getId()));
            }
        }else {
            //没有组织删除所有角色
            userRoleMapper.delete(Wrappers.<SysUserRole>lambdaQuery()
                    .eq(SysUserRole::getUserId,user.getId()));
        }
        //上传图片
        if(data.getFile()!=null){
            saveFiles(user.getId(),data.getFile(),upfolder,accessPath);
        }
        return ret == 1 ? ResultUtil.ok() : ResultUtil.fail();
    }

    @Override
    public ResultUtil<T> changeUserPassword(SysUserVo data) {
        SysUser user = userMapper.selectById(data.getId());

        ResultUtil<T> rel = securityService.checkPasswordLevel(data.getPassword());
        if (rel.getCode()==400){
            return rel;
        }

        if (user.getPassword().trim().equals(data.getOldpassword().trim())) {
            user.setPassword(data.getPassword());
            int ret = userMapper.updateById(user);

            // 同步修改小程序密码
            userMemberMapper.update(null, new UpdateWrapper<UserMember>().eq("disable", 0)
                    .eq("username", user.getMobile()).set("password", user.getPassword()));
            return ret > 0 ? ResultUtil.ok() : ResultUtil.fail();
        } else {
            return ResultUtil.build(ResultUtilCodeEnum.OLD_PASSWORD_ERROR);
        }
    }

    @Override
    public List<Long> getUserList(Long userId) {
        return baseMapper.selectUserList(userId);
    }

    @Override
    public boolean unlockRet(SysUserVo vo) {
        boolean b = false;
        SysUser sysUser = baseMapper.selectById(vo.getId());
        sysUser.setLoginNum(0);
        sysUser.setLoginTime(null);
        b = updateById(sysUser);
        return b;
    }

    public void saveFiles(Long id, MultipartFile files, String upfolder, String accessPath) {
        //设置日期格式
        DateTimeFormatter formatters = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        //当地日期转换
        String dayFormat = LocalDate.now().format(formatters);
        //创建新文件：通过路径和时间
        File folder = new File(upfolder + File.separator + dayFormat);
        //文件是否存在，不存在进行创建。
        if (!folder.exists()) {
            folder.mkdirs();
        }
        //获取文件名
        String regEx1 = "[`~!@#$%^&*()+=|{}':;',\\[\\]<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？]";
        String fileName = files.getOriginalFilename();
        String urlName=(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))+ Pattern.compile(regEx1).matcher(fileName).replaceAll("").trim());
        //设置路径
        String path = folder + File.separator;
        File file = getFileByName(1, path, urlName);
        try {
            // 上传文件到服务器
            files.transferTo(file);
            SysUser sysUser = getById(id);
            sysUser.setAvatarUrl(accessPath.substring(0, accessPath.lastIndexOf("/")) + "/" + dayFormat+"/"+file.getName());
            boolean b = updateById(sysUser);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private File getFileByName(int count, String path, String fileName) {
        File file = new File(path + fileName);
        if (file.exists()) {
            // 文件名已存在
            String prefix = fileName.substring(0, fileName.lastIndexOf(".")) + "(" + count + ")";
            String suffixName = fileName.substring(fileName.lastIndexOf("."));
            file = getFileByName(count + 1, path, prefix + suffixName);
        }
        return file;
    }
}
